package Farsail::Action;

use strict; 
use warnings;
use Carp;

use overload
    '""' => \&full_name;

sub new {
    my $_class = shift;
    my $class = ref $_class || $_class;

    my ($actions, $ns, $name) = @_;
    my $self = $actions->{$name} || {};
    $self->{name} = $name;
    $self->{namespace} = $ns;
    $self->{parent} = $actions;
    $self->{module} ||= $actions->{module};
    bless $self, $class;
    return $self;
}

sub namespace {
    my $self = shift;
    return $self->{namespace};
}

sub name {
    my $self = shift;
    return $self->{name};
}

sub full_name {
    my $self = shift;
    return join('.',$self->{namespace}, $self->{name});
}

sub parent {
    my $self = shift;
    return $self->{parent};
}

sub module {
    my $self = shift;
    return $self->{module};
}

sub check {
    return shift->{check};
}

sub depends {
    my $self = shift;
    if ( exists $self->{depends} ) {
        return map {
            /\./ ? $_ : "$self->{namespace}.$_"
        } grep { $_ } @{$self->{depends}};
    } else {
        return ();
    }
}

sub args {
    my $self = shift;
    if ( !exists $self->{cooked_args} ) {
        my $args_type = $self->parent->{args_type};
        my %args;
        if ( $self->{args} && ref $self->{args} eq 'HASH' ) {
            %args = %{$self->{args}};
        }
        for ( keys %args ) {
            my $opt = $args{$_};
            if ( !ref $opt ) {
                $opt = { type => $opt };
            }
            if ( exists $args_type->{ $opt->{type} } ) {
                my $def = $args_type->{ delete $opt->{type} };
                for ( keys %$def ) {
                    $opt->{$_} = $def->{$_} if !exists $opt->{$_};
                }
            }
            $args{$_} = $opt;
        }
        $self->{cooked_args} = \%args;
    }
    return $self->{cooked_args};
}

1;
